package com.wenbing.miio.core;

import java.time.Clock;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 网络协议栈 是连接内外的通道
 * 连接外部网络接口，解码来自外部的数据, 编码内部的数据
 * 作为网络接口对内提供服务
 * @author wen bing
 * @projectName: miio
 * @package: com.wenbing.miio.core
 * @className: NetworkStacks
 * @date 2024/09/23 21:46
 **/
public interface NetworkStack extends Bootable {

    final class NetworkLayerNode {

        private NetworkLayer layer;

        private NetworkLayerNode lowerLayerNode;

        private NetworkLayerNode upperLayerNode;

        private NetworkStack networkStack;

        NetworkLayerNode() {

        }

        void setLayer(NetworkLayer layer) {
            this.layer = layer;
        }

        void setNetworkStack(NetworkStack networkStack) {
            this.networkStack = networkStack;
        }

        public NetworkLayer getLayer() {
            return layer;
        }

        void setLowerLayerNode(NetworkLayerNode lowerLayerNode) {
            this.lowerLayerNode = lowerLayerNode;
        }

        protected NetworkLayerNode getLowerLayerNode() {
            return lowerLayerNode;
        }

        public NetworkLayer getLowerLayer() {
            return lowerLayerNode == null ? null : lowerLayerNode.layer;
        }

        void setUpperLayerNode(NetworkLayerNode upperLayerNode) {
            this.upperLayerNode = upperLayerNode;
        }

        NetworkLayerNode getUpperLayerNode() {
            return upperLayerNode;
        }

        public NetworkLayer getUpperLayer() {
            return upperLayerNode == null ? null : upperLayerNode.layer;
        }

        public NetworkStack getNetworkStack() {
            return this.networkStack;
        }

        public static void link(NetworkLayerNode upper, NetworkLayerNode lower) {
            upper.lowerLayerNode = lower;
            lower.upperLayerNode = upper;
        }
    }

    /**
     * 获取网络栈时钟
     * @return
     */
    Clock getClock();

    /**
     * 获取网络栈的配置
     * @return
     */
    Device.HardwareConfiguration getConfiguration();

    /**
     * 添加底层协议
     * @param layer
     */
    void addLowerLayer(NetworkLayer layer);
}
